package com.leilei.serviceProject.domain.strategy.service.raffle;

import com.leilei.serviceProject.domain.strategy.model.entity.RaffleFactorEntity;
import com.leilei.serviceProject.domain.strategy.model.valobj.RuleTreeVo;
import com.leilei.serviceProject.domain.strategy.model.valobj.StrategyAwardCountSurplusVo;
import com.leilei.serviceProject.domain.strategy.model.valobj.StrategyAwardRuleModelVo;
import com.leilei.serviceProject.domain.strategy.repository.IStrategyRepository;
import com.leilei.serviceProject.domain.strategy.service.AbstractRaffleStrategy;
import com.leilei.serviceProject.domain.strategy.service.rule.chain.ILogicChain;
import com.leilei.serviceProject.domain.strategy.service.rule.chain.factory.DefaultLogicChainFactory;
import com.leilei.serviceProject.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import com.leilei.serviceProject.domain.strategy.service.rule.tree.factory.engine.impl.RuleTreeEngine;
import com.leilei.serviceProject.types.enums.ResponseCode;
import com.leilei.serviceProject.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author yanglei
 * @description 默认抽奖策略实现
 * @create 2024/10/24 16:17
 */
@Slf4j
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy {
    @Resource
    private IStrategyRepository strategyRepository;
    @Resource
    private DefaultLogicChainFactory logicChainFactory;
    @Resource
    private DefaultTreeFactory treeFactory;

    @Override
    protected void raffleParamVerification(RaffleFactorEntity raffleFactor) {
        String userId = raffleFactor.getUserId();
        Long strategyId = raffleFactor.getStrategyId();
        if (StringUtils.isBlank(userId) || null == strategyId) {
            log.error("参数校验失败，userID：{} strategyId：{}", userId, strategyId);
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }
    }

    @Override
    protected Integer raffleLogicChain(RaffleFactorEntity raffleFactor) {
        ILogicChain logicChain = logicChainFactory.openLogicChain(raffleFactor.getStrategyId());
        return logicChain.logic(raffleFactor);
    }

    @Override
    protected DefaultTreeFactory.TreeResultData raffleLogicTree(Long strategyId, String userId, Integer awardId) {
        // 1.动态获取树
        StrategyAwardRuleModelVo ruleModel = strategyRepository.queryStrategyAwardRuleModelsEntity(strategyId, awardId);
        if (null == ruleModel) {
            return DefaultTreeFactory.TreeResultData.builder()
                    .awardId(awardId)
                    .build();
        }
        RuleTreeVo ruleTreeVo = strategyRepository.queryRuleTreeVoByTreeId(ruleModel.getRuleModels());
        if (null == ruleTreeVo) {
            throw new RuntimeException("存在抽奖策略配置的规则模型 Key，未在库表 rule_tree、rule_tree_node、rule_tree_line 配置对应的规则树信息 " + ruleModel.getRuleModels());
        }
        // 2.构建规则树树引擎
        RuleTreeEngine treeEngine = treeFactory.openTreeEngine(ruleTreeVo);
        // 3.则树树引擎抽奖
        return treeEngine.process(strategyId, userId, awardId);
    }

    @Override
    public StrategyAwardCountSurplusVo takeQueueValue() throws InterruptedException {
        return strategyRepository.takeQueueValue();
    }

    @Override
    public void updateStrategyAwardStock(Long strategyId, Integer awardId) {
        strategyRepository.updateStrategyAwardStock(strategyId, awardId);
    }

}
